using System;
using System.IO;
using ExtensionOverflow;

namespace SimpleScheduler.Convert
{
    public class Converter
    {
        public void Run()
        {
            ArrayOfJobClass jobs = ArrayOfJobClass.Load(@"C:\Documents and Settings\npalmer\Desktop\settings\jobs.xml");
            
            foreach(var job in jobs.JobClass)
            {
                string group = "Default";
                Core.Domain.Job j = new Core.Domain.Job();

                var nameSplit = job.Name.Split(' ');
                if (nameSplit.Length > 0 && nameSplit[0].ToUpper() == nameSplit[0])
                {
                    group = nameSplit[0];
                    j.Name = job.Name.Replace(nameSplit[0],"");
                }
                else
                {
                    j.Name = job.Name;
                }

                j.Name = j.Name.Trim().Replace("<", "").Replace("\\","").Replace(":","");

                j.Enabled = job.Stats.Active;

                //if (job.Name.Equals("ADMIN AWS Processor (XML Processor 2.7)")) System.Diagnostics.Debugger.Break();
                Console.WriteLine(job.Name);

                j.Description = job.Description;
                j.Type = "SimpleScheduler.Job.MultiTaskJob, SimpleScheduler.Core";

                j.Tasks = new Core.Domain.TaskCollection();                
                foreach (var task in job.Tasks)
                {
                    Core.Domain.Task t = new Core.Domain.Task();

                    string taskType = task.Items[7].ToString();
                    switch (taskType)
                    {
                        case "Execute":
                            if (task.Items[8] is ArrayOfJobClassJobClassTaskClassExecute)
                            {
                                ArrayOfJobClassJobClassTaskClassExecute executeContext = (ArrayOfJobClassJobClassTaskClassExecute)task.Items[8];

                                //jobDetail = new JobDetail(guid.ToString(), jobGroup, typeof(ShellExecuteJob));
                                t.Name = task.Items[12].ToString();
                                //t.Type = "SimpleScheduler.Job.CommandLineJob, SimpleScheduler.Core";
                                t.Type = "SimpleScheduler.Job.DoNothingJob, SimpleScheduler.Core";
                                t.Properties = new Core.Domain.PropertyCollection();
                                t.Properties.Add(new Core.Domain.Property("Command", executeContext.CmdLine));
                                t.Properties.Add(new Core.Domain.Property("Arguments", executeContext.Arguments));
                                t.Properties.Add(new Core.Domain.Property("Hidden", executeContext.RunHidden.ToString()));
                                t.Properties.Add(new Core.Domain.Property("WorkingDirectory", executeContext.WorkingDirectory));

                                if (executeContext.CheckIfRunning == true) throw new Exception();
                                //Console.WriteLine(executeContext.CheckIfRunning);
                                if (executeContext.Priority != "Normal") throw new Exception();
                                //Console.WriteLine(executeContext.Priority);
                                //Console.WriteLine(executeContext.ProcessName);
                                if (executeContext.RunAsType != "API") throw new Exception();
                                //Console.WriteLine(executeContext.RunAsType);
                                
                                //jobDetail.JobDataMap.Put("NetworkCredential", executeContext.NetworkCredential);
                                //jobDetail.JobDataMap.Put("LogonType", executeContext.LogonType);
                                //jobDetail.JobDataMap.Put("UseCredentials", executeContext.UseCredentials);
                                //jobDetail.JobDataMap.Put("UseShellExecute", executeContext.UseShellExecute);
                                //jobDetail.JobDataMap.Put("UseWorkingDirectory", executeContext.UseWorkingDirectory);
                                //jobDetail.JobDataMap.Put("WorkingDirectory", executeContext.WorkingDirectory);

                                //jobDetail.JobDataMap.Put("Arguments", executeContext.Arguments);
                                //jobDetail.JobDataMap.Put("CmdLine", executeContext.CmdLine);
                                //jobDetail.JobDataMap.Put("RunHidden", executeContext.RunHidden);
                            }
                            else
                            {
                                throw new InvalidCastException("Item 8 is not of correct type");
                            }
                            break;
                        case "SQL":
                            if (task.Items[8] is ArrayOfJobClassJobClassTaskClassSQL)
                            {
                                ArrayOfJobClassJobClassTaskClassSQL executeContext = (ArrayOfJobClassJobClassTaskClassSQL)task.Items[8];
                            }
                            else
                            {
                                throw new InvalidCastException("Item 8 is not of correct type");
                            }
                            break;
                        case "CopyFile":
                        case "ExportSettings":
                        
                        case "FTP":
                        case "FileDelete":
                        case "FileRename":
                        case "Email":
                        default:
                            //if (job.Triggers)
                            switch (job.Name)
                            {
                                case "ADMIN Backup":
                                case "ADMIN Backup settings":
                                //case "PROJECTTRACKING CleanupXmlData":
                                //case "ADMIN Insert and Update Active Directory Table":
                                case "ADMIN Expense Report Email":
                                    break;
                                default:
                                    throw new Exception(string.Format("{0} is not supported", taskType));
                            }
                            break;
                    }

                    j.Tasks.Add(t);                    
                }

                j.Triggers = new Core.Domain.TriggerCollection();
                foreach (ArrayOfJobClassJobClassTriggerClass trigger in job.Triggers)
                {
                    var t = new Core.Domain.Trigger();

                    t.Enabled = trigger.Active;

                    if (trigger.TTime.TimeTriggerType == "Interval")
                    {
                        t.Type = "Simple";

                        switch(trigger.TTime.IntervalType)
                        {
                            case "Minutely":
                                t.RepeatInterval = trigger.TTime.IntervalValue*60;
                                break;
                            case "Hourly":
                                t.RepeatInterval = trigger.TTime.IntervalValue*60*60;
                                break;
                            case "Daily":
                                t.RepeatInterval = trigger.TTime.IntervalValue*24*60*60;
                                break;
                            default:
                                throw new Exception(string.Format("{0} trigger is not supported", trigger.TTime.IntervalType));
                        }
                    }
                    else
                    {
                        t.Type = "Cron";

                        t.Second = (trigger.TTime.AllSeconds) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Seconds);
                        t.Minute = (trigger.TTime.AllMinutes) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Minutes);
                        t.Hour = (trigger.TTime.AllHours) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Hours);
                        t.DayOfWeek = (trigger.TTime.AllDays) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Days, 1);
                        t.Month = (trigger.TTime.AllMonths) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Months, 1);
                        t.Year = (trigger.TTime.AllYears) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Years);
                    }

                    j.Triggers.Add(t);
                    //             cronString =
                    //((trigger.TTime.AllSeconds) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Seconds)) + " " +
                    //((trigger.TTime.AllMinutes) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Minutes)) + " " +
                    //((trigger.TTime.AllHours) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Hours)) + " " +
                    //((trigger.TTime.IntervalType.Equals("SpecificDaysOfTheWeek"))
                    //     ? "?"
                    //     : ((trigger.TTime.AllDays) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Days, 1))) + " " +
                    //((trigger.TTime.AllMonths) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Months, 1)) + " " +
                    //((trigger.TTime.IntervalType.Equals("SpecificDaysOfTheWeek"))
                    //     ? ArrayToCommaDelimitedString(trigger.TTime.IntervalWeekDays, 1) + ""
                    //     : "?") + " " +
                    //((trigger.TTime.AllYears) ? "*" : ArrayToCommaDelimitedString(trigger.TTime.Years));
                    //             log.Trace(trigger.TTime.DateNextExecution.ToString() + ": " + cronString);
                    //             jobDetailTrigger = new CronTrigger(triggerGuid.ToString(), "Default", cronString);

                }

                var fi = new FileInfo(Path.Combine(@"C:\Source\OpenSource\SimpleScheduler\Source\SimpleScheduler.Server\bin\Debug\Jobs", string.Format(@"{0}\{1}.xml", group, j.Name)));
                j.Save(fi);                
            }
        }

        string ArrayToCommaDelimitedString(bool[] IntervalArray)
        {
            return ArrayToCommaDelimitedString(IntervalArray, 0);
        }

        string ArrayToCommaDelimitedString(bool[] IntervalArray, int Offset)
        {
            string intervalList = String.Empty;
            for (int i = 0; i < IntervalArray.Length; i++)
            {
                if (IntervalArray[i])
                {
                    if (intervalList.Length > 0)
                    {
                        intervalList += ",";
                    }
                    intervalList += string.Format("{0}", i + Offset);
                }
            }
            return intervalList;
        }

        string ArrayToCommaDelimitedString(ushort[] IntervalArray)
        {
            string intervalList = String.Empty;
            for (int i = 0; i < IntervalArray.Length; i++)
            {
                if (IntervalArray[i] != 0)
                {
                    intervalList += string.Format("{0}", IntervalArray[i]);
                }
            }
            return intervalList;
        }
    }
}